<template>
	<view class="page-container">
		<view class="page-header">
			<view class="header-left">
				<text class="page-title">产品管理</text>
				<text class="page-subtitle">管理和维护所有产品信息</text>
			</view>
			<view class="header-right">
				<button class="btn btn-primary" @click="handleAdd"><text class="icon">+</text> 新增产品</button>
			</view>
		</view>
		<view class="filter-section">
			<view class="search-box">
				<input v-model="searchParams.keyword" type="text" placeholder="搜索产品名称、分类..." class="search-input" @confirm="handleSearch" />
				<button class="btn-search" @click="handleSearch">搜索</button>
				<button class="btn-reset" @click="handleReset">重置</button>
			</view>
			<view v-if="selectedIds.length > 0" class="batch-actions">
				<text class="batch-count">已选中 {{ selectedIds.length }} 项</text>
				<button class="btn btn-danger btn-small" @click="handleBatchDelete">删除选中</button>
				<button class="btn btn-default btn-small" @click="handleCancelSelect">取消选择</button>
			</view>
		</view>
		<view class="table-wrapper">
			<view v-if="loading" class="loading-state"><text class="loading-text">加载中...</text></view>
			<view v-else-if="dataList.length === 0" class="empty-state"><text class="empty-icon">📭</text><text class="empty-text">暂无产品数据</text><button class="btn btn-primary" @click="handleAdd">新增产品</button></view>
			<view v-else class="table-container">
				<view class="table-header">
					<view class="table-cell checkbox-cell"><checkbox-group @change="handleSelectAll"><label><checkbox :checked="isSelectAll" value="all" /></label></checkbox-group></view>
					<view class="table-cell col-name">产品名称</view>
					<view class="table-cell col-type">产品类型</view>
					<view class="table-cell col-base-price">基础价格</view>
					<view class="table-cell col-promotion">促销活动</view>
					<view class="table-cell col-promotion-target">促销对象</view>
					<view class="table-cell col-final-price">优惠价格</view>
					<view class="table-cell col-stock">库存</view>
					<view class="table-cell col-status">状态</view>
					<view class="table-cell col-actions">操作</view>
				</view>
				<view v-for="item in dataList" :key="item._id" class="table-row" :class="{ selected: selectedIds.includes(item._id) }">
					<view class="table-cell checkbox-cell" @click.stop><checkbox-group @change="(e) => handleSelectItem(item._id, e)"><label><checkbox :checked="selectedIds.includes(item._id)" :value="item._id" /></label></checkbox-group></view>
					<view class="table-cell col-name clickable" @click="handleView(item._id)"><text class="cell-text">{{ item.product_name }}</text></view>
					<view class="table-cell col-type clickable" @click="handleView(item._id)"><text class="cell-text">{{ getProductTypeText(item.product_type) }}</text></view>
					<view class="table-cell col-base-price clickable" @click="handleView(item._id)"><text class="cell-text">¥{{ item.price || 0 }}</text></view>
					<view class="table-cell col-promotion clickable" @click="handleView(item._id)">
						<text class="cell-text" v-if="item.priceInfo && item.priceInfo.promotionInfo">{{ item.priceInfo.promotionInfo.ruleName }}</text>
						<text class="cell-text text-muted" v-else>未促销</text>
					</view>
					<view class="table-cell col-promotion-target clickable" @click="handleView(item._id)">
						<text class="cell-text" v-if="item.priceInfo && item.priceInfo.promotionInfo">{{ getPromotionTargetText(item.priceInfo.promotionInfo) }}</text>
						<text class="cell-text text-muted" v-else>无</text>
					</view>
					<view class="table-cell col-final-price clickable" @click="handleView(item._id)">
						<view class="price-display">
							<text class="final-price" :class="{ 'has-discount': item.priceInfo && item.priceInfo.promotionInfo }">¥{{ item.priceInfo ? item.priceInfo.finalPrice : (item.price || 0) }}</text>
							<text v-if="item.priceInfo && item.priceInfo.savingAmount > 0" class="saving-badge">省¥{{ item.priceInfo.savingAmount }}</text>
						</view>
					</view>
					<view class="table-cell col-stock clickable" @click="handleView(item._id)"><text class="cell-text">{{ item.stock_quantity || 0 }}</text></view>
					<view class="table-cell col-status clickable" @click="handleView(item._id)">
						<text class="status-badge" :class="'status-' + (item.status === 1 ? 'active' : 'inactive')">{{ getStatusText(item.status) }}</text>
					</view>
					<view class="table-cell col-actions" @click.stop>
						<button class="action-btn edit-btn" @click="handleEdit(item._id)">编辑</button>
						<button class="action-btn delete-btn" @click="handleDelete(item._id)">删除</button>
					</view>
				</view>
			</view>
		</view>
		<view v-if="dataList.length > 0" class="pagination-section">
			<view class="pagination-info"><text>共 {{ total }} 条数据，第 {{ currentPage }} / {{ totalPages }} 页</text>
				<view class="page-size-selector"><text class="selector-label">每页显示</text><picker mode="selector" :range="pageSizeOptions" :value="pageSizeIndex" @change="handlePageSizeChange" class="selector-picker"><view class="selector-input">{{ pageSize }} 条</view></picker></view>
			</view>
			<view class="pagination-controls">
				<button :disabled="currentPage === 1" class="btn btn-default btn-small" @click="handlePreviousPage">上一页</button>
				<button :disabled="currentPage === totalPages" class="btn btn-default btn-small" @click="handleNextPage">下一页</button>
			</view>
		</view>
	</view>
</template>
<script setup>
import { ref, computed, onMounted } from 'vue'
const dataList = ref([]), loading = ref(false), total = ref(0), currentPage = ref(1), pageSize = ref(20)
const pageSizeOptions = ['10 条', '20 条', '50 条', '100 条'], pageSizeValues = [10, 20, 50, 100]
const pageSizeIndex = computed(() => pageSizeValues.indexOf(pageSize.value))
const searchParams = ref({ keyword: '' }), selectedIds = ref([])
const totalPages = computed(() => Math.ceil(total.value / pageSize.value))
const isSelectAll = computed(() => dataList.value.length > 0 && dataList.value.length === selectedIds.value.length)
onMounted(() => { loadData() })
async function loadData() {
	loading.value = true
	try {
		const dhProducts = uniCloud.importObject('dh-products')
		const skip = (currentPage.value - 1) * pageSize.value
		const query = searchParams.value.keyword ? { product_name: new RegExp(searchParams.value.keyword) } : {}
		const result = await dhProducts.listProductsWithPrices(query, skip, pageSize.value)
		if (result.code === 200) {
			dataList.value = result.data || []
			total.value = result.count || 0
			selectedIds.value = []
		} else { uni.showToast({ title: result.message || '加载失败', icon: 'error' }) }
	} catch (error) {
		console.error('加载数据失败:', error)
		uni.showToast({ title: '加载数据失败', icon: 'error' })
	} finally { loading.value = false }
}
function getProductTypeText(type) {
	const typeMap = {
		1: '药品',
		2: '医疗器材',
		3: '其他'
	}
	return typeMap[type] || '未知'
}
function getStatusText(status) {
	const statusMap = {
		1: '在售',
		2: '停售',
		3: '禁用'
	}
	return statusMap[status] || '未知'
}
function getPromotionTargetText(promotionInfo) {
	if (!promotionInfo) return '无'
	// TODO: 根据促销规则的目标用户标签返回文本
	// 这里可以扩展，根据实际业务需求显示目标用户群体
	return '全部用户'
}
function handleSearch() { currentPage.value = 1; loadData() }
function handleReset() { searchParams.value.keyword = ''; currentPage.value = 1; loadData() }
function handleSelectItem(id, e) { const values = e.detail.value; if (values.includes(id)) { if (!selectedIds.value.includes(id)) selectedIds.value.push(id) } else { const index = selectedIds.value.indexOf(id); if (index > -1) selectedIds.value.splice(index, 1) } }
function handleSelectAll(e) { const values = e.detail.value; if (values.includes('all')) { selectedIds.value = dataList.value.map(item => item._id) } else { selectedIds.value = [] } }
function handleCancelSelect() { selectedIds.value = [] }
function handleAdd() { uni.navigateTo({ url: '/pages/business/products/add' }) }
function handleView(id) { uni.navigateTo({ url: `/pages/business/products/detail?id=${id}` }) }
function handleEdit(id) { uni.navigateTo({ url: `/pages/business/products/edit?id=${id}` }) }
async function handleDelete(id) {
	const confirmed = await showConfirm('确认删除', '确定要删除此产品吗？')
	if (!confirmed) return
	try {
		const dhProducts = uniCloud.importObject('dh-products')
		const result = await dhProducts.deleteProduct(id)
		if (result.code === 200) { uni.showToast({ title: '删除成功', icon: 'success' }); loadData() } else { uni.showToast({ title: result.message || '删除失败', icon: 'error' }) }
	} catch (error) { console.error('删除失败:', error); uni.showToast({ title: '删除失败', icon: 'error' }) }
}
async function handleBatchDelete() {
	if (selectedIds.value.length === 0) { uni.showToast({ title: '请选择要删除的项', icon: 'warning' }); return }
	const confirmed = await showConfirm('批量删除', `确定要删除选中的 ${selectedIds.value.length} 项吗？`)
	if (!confirmed) return
	try {
		const dhProducts = uniCloud.importObject('dh-products')
		const result = await dhProducts.batchDeleteProducts(selectedIds.value)
		if (result.code === 200) { uni.showToast({ title: '批量删除成功', icon: 'success' }); selectedIds.value = []; loadData() } else { uni.showToast({ title: result.message || '批量删除失败', icon: 'error' }) }
	} catch (error) { console.error('批量删除失败:', error); uni.showToast({ title: '批量删除失败', icon: 'error' }) }
}
function handlePreviousPage() { if (currentPage.value > 1) { currentPage.value--; loadData() } }
function handleNextPage() { if (currentPage.value < totalPages.value) { currentPage.value++; loadData() } }
function handlePageSizeChange(e) { const index = e.detail.value; pageSize.value = pageSizeValues[index]; currentPage.value = 1; loadData() }
function showConfirm(title, content) { return new Promise((resolve) => { uni.showModal({ title, content, confirmText: '确定', cancelText: '取消', success: (res) => { resolve(res.confirm) } }) }) }
</script>
<style scoped lang="scss">
.page-container { padding: 20px; background-color: #f5f7fa; min-height: 100vh; }
.page-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px; background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); }
.header-left { display: flex; flex-direction: column; }
.page-title { font-size: 20px; font-weight: 600; color: #1f2937; margin-bottom: 4px; }
.page-subtitle { font-size: 12px; color: #6b7280; }
.header-right { display: flex; gap: 10px; }
.btn { padding: 6px 14px; border-radius: 6px; border: none; cursor: pointer; font-size: 14px; font-weight: 500; transition: all 0.3s ease; display: inline-flex; align-items: center; gap: 6px; height: 34px; box-sizing: border-box; &:disabled { opacity: 0.5; cursor: not-allowed; } &.btn-primary { background-color: #3b82f6; color: white; &:active { background-color: #2563eb; } } &.btn-default { background-color: #e5e7eb; color: #374151; &:active { background-color: #d1d5db; } } &.btn-danger { background-color: #ef4444; color: white; &:active { background-color: #dc2626; } } &.btn-small { padding: 6px 12px; font-size: 12px; } }
.icon { font-size: 16px; }
.filter-section { display: flex; flex-direction: column; gap: 16px; margin-bottom: 20px; }
.search-box { display: flex; gap: 8px; background: white; padding: 12px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); }
.search-input { flex: 1; padding: 8px 12px; border: 1px solid #d1d5db; border-radius: 6px; font-size: 14px; height: 38px; box-sizing: border-box; &:focus { outline: none; border-color: #3b82f6; box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1); } }
.btn-search { padding: 8px 16px; background-color: #3b82f6; color: white; border: 1px solid #3b82f6; border-radius: 6px; cursor: pointer; font-size: 14px; font-weight: 500; height: 38px; box-sizing: border-box; display: flex; align-items: center; &:active { background-color: #2563eb; } }
.btn-reset { padding: 8px 16px; background-color: #e5e7eb; color: #374151; border: 1px solid #e5e7eb; border-radius: 6px; cursor: pointer; font-size: 14px; font-weight: 500; height: 38px; box-sizing: border-box; display: flex; align-items: center; &:active { background-color: #d1d5db; } }
.batch-actions { display: flex; align-items: center; gap: 12px; background: white; padding: 12px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); }
.batch-count { font-size: 14px; color: #6b7280; font-weight: 500; }
.table-wrapper { background: white; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); margin-bottom: 20px; }
.loading-state, .empty-state { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 60px 20px; }
.loading-text { font-size: 14px; color: #6b7280; }
.empty-icon { font-size: 48px; margin-bottom: 12px; }
.empty-text { font-size: 14px; color: #6b7280; margin-bottom: 16px; }
.table-container { overflow-x: auto; }
.table-header { display: grid; grid-template-columns: 40px 150px 100px 100px 120px 120px 120px 80px 80px 140px; gap: 12px; padding: 12px 16px; background-color: #f9fafb; border-bottom: 1px solid #e5e7eb; font-size: 12px; font-weight: 600; color: #6b7280; text-transform: uppercase; letter-spacing: 0.5px; .table-cell { justify-content: center; } }
.table-row { display: grid; grid-template-columns: 40px 150px 100px 100px 120px 120px 120px 80px 80px 140px; gap: 12px; padding: 12px 16px; border-bottom: 1px solid #e5e7eb; align-items: center; transition: background-color 0.2s ease, border-left 0.2s ease; &:hover { background-color: #f9fafb; } &:last-child { border-bottom: none; } &.selected { background-color: #eff6ff; border-left: 3px solid #3b82f6; padding-left: 13px; } .table-cell { justify-content: center; } .col-actions { justify-content: flex-end; } }
.table-cell { display: flex; align-items: center; }
.checkbox-cell { justify-content: center; checkbox-group { display: flex; align-items: center; justify-content: center; } label { display: flex; align-items: center; justify-content: center; cursor: pointer; } checkbox { transform: scale(1.1); } }
.cell-text { font-size: 14px; color: #1f2937; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; &.text-muted { color: #9ca3af; } }
.status-badge { display: inline-block; padding: 4px 12px; border-radius: 4px; font-size: 12px; font-weight: 600; &.status-active { background-color: #d1fae5; color: #065f46; } &.status-inactive { background-color: #fee2e2; color: #7f1d1d; } }
.price-display { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.final-price { font-size: 14px; color: #1f2937; font-weight: 600; &.has-discount { color: #ef4444; font-size: 15px; } }
.saving-badge { font-size: 11px; color: #16a34a; background-color: #dcfce7; padding: 2px 6px; border-radius: 3px; font-weight: 500; }
.col-actions { display: flex; gap: 6px; justify-content: flex-end; }
.clickable { cursor: pointer; transition: background-color 0.2s ease; &:hover { background-color: #f9fafb; } }
.action-btn { padding: 4px 10px; border: none; border-radius: 4px; cursor: pointer; font-size: 12px; font-weight: 500; transition: all 0.3s ease; white-space: nowrap; height: 26px; display: flex; align-items: center; box-sizing: border-box; &.edit-btn { background-color: #fef3c7; color: #92400e; &:hover { background-color: #fde68a; } &:active { background-color: #fcd34d; } } &.delete-btn { background-color: #fee2e2; color: #991b1b; &:hover { background-color: #fecaca; } &:active { background-color: #fca5a5; } } }
.pagination-section { display: flex; justify-content: space-between; align-items: center; background: white; padding: 16px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); }
.pagination-info { display: flex; align-items: center; gap: 16px; font-size: 12px; color: #6b7280; }
.page-size-selector { display: flex; align-items: center; gap: 8px; }
.selector-label { font-size: 12px; color: #6b7280; }
.selector-picker { flex-shrink: 0; }
.selector-input { padding: 4px 8px; border: 1px solid #d1d5db; border-radius: 4px; font-size: 12px; color: #374151; background-color: white; cursor: pointer; min-width: 70px; text-align: center; }
.pagination-controls { display: flex; gap: 8px; }
@media (max-width: 768px) {
	.page-container { padding: 12px; }
	.page-header { flex-direction: row; align-items: center; gap: 8px; padding: 12px; }
	.header-left { flex: 1; min-width: 0; }
	.header-right { flex-shrink: 0; }
	.page-title { font-size: 16px; }
	.page-subtitle { font-size: 11px; line-height: 1.4; }
	.btn { padding: 6px 12px; font-size: 13px; height: auto; }
	.search-box { flex-wrap: wrap; }
	.search-input { width: 100%; flex: 1 1 100%; margin-bottom: 8px; }
	.btn-search, .btn-reset { flex: 1; justify-content: center; }
	.batch-actions { flex-wrap: wrap; }
	.table-wrapper { overflow-x: auto; }
	.table-container { min-width: 1200px; }
	.pagination-section { flex-direction: column; gap: 12px; align-items: flex-start; }
	.pagination-info { flex-direction: column; align-items: flex-start; gap: 8px; width: 100%; }
	.page-size-selector { width: 100%; justify-content: space-between; }
	.selector-picker { flex: 0 0 auto; }
	.selector-input { min-width: 80px; }
	.pagination-controls { width: 100%; justify-content: space-between; }
	.btn.btn-small { flex: 1; }
}
</style>
